home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / linkedit / linkedit.lha / link-edit / LinkEdit / Choose / choose.c next >
Encoding:
C/C++ Source or Header  |  1991-03-13  |  13.9 KB  |  482 lines

  1. #include <X11/Xlib.h>
  2. #include <X11/Xutil.h>
  3. #include <X11/cursorfont.h>
  4. #include <stdio.h>
  5. #include <sys/types.h>
  6. #include <dirent.h>
  7. #include <malloc.h>
  8.  
  9. #define MaxFiles 100
  10. #define MaxName 100
  11. #define MaxSuff 100
  12. #define mystuff mydisplay, mywindow, mygc
  13. #define rmystuff mydisplay, mywindow, rmygc
  14. #define font "9x15"   /* 9x15 */
  15. #define min(A,B) ((A>=B) ? B : A)
  16. #define max(A,B) ((A>=B) ? A : B)
  17. #define message(A); XFillRectangles(mystuff,&messbox,1); \
  18.   XDrawString(rmystuff,messbox.x+5,messbox.y+letheight, A, strlen(A));
  19.  
  20. char *choose_dir;
  21. static XSizeHints myhint;
  22. static shwdir=1;
  23. static char *sufv[MaxSuff]; 
  24. static int sufc=0;
  25. static XFontStruct *font_struct;
  26. static int letwidth=6;
  27. static int letheight=13;
  28. static int rows=10;
  29. static XRectangle lstbox,cancelbox,okbox,fnamebox,upbox,downbox,mvbox,messbox;
  30. static char *prompt_string="file name: ";
  31.  
  32.   
  33.  
  34. static  int firstcall=0;
  35. static  Display *mydisplay;
  36. static  Window mywindow,UrgWindow;
  37. static  XWindowAttributes sizeatt;
  38. static  GC mygc,rmygc;
  39. static  XEvent event,myevent;
  40. static  Cursor curs1,curs2;
  41. static  unsigned long myforeground, mybackground;
  42. static  KeySym mykey;
  43. static  int myscreen;
  44.  
  45. /* TOBY addition */
  46. extern Display *dpy;
  47.  
  48.  
  49. struct elm {
  50.   int chose;
  51.   int ftype;
  52.   char name[MaxName];
  53. };
  54.  
  55. int
  56. showdir(which)
  57.   int which;
  58. {  shwdir=which; return(which); }
  59.  
  60. int
  61. addsuff(name)
  62.   char *name;
  63. { if (sufc<MaxSuff)
  64.   { sufc++;
  65.     *(sufv+sufc-1)=(char *)malloc((strlen(name)+2)*sizeof(char));
  66.     strcpy(*(sufv+sufc-1),name); return(1);
  67.   }
  68.   else return(0);
  69. }
  70.  
  71. int
  72. clearsuff()
  73. { int t;
  74.   for(t=0; t<sufc; t++) free(*(sufv+t));
  75.   sufc=0;
  76. }
  77. int
  78. delsuff(name)
  79.   char *name;
  80. { int t,t2,good=0;
  81.   for(t=0; t<sufc; t++)
  82.     if (strcmp(name,*(sufv+t))==0)
  83.     { free(*(sufv+t)); 
  84.       good=1;
  85.       for(t2=t; t2<sufc; t2++) *(sufv+t2) = *(sufv+t2+1);
  86.       t--;
  87.       sufc--;
  88.     }
  89.    return(good);
  90. }
  91.  
  92. int
  93. suflist(name)
  94.   char *name;
  95. { int t;
  96.   if (sufc==0) return(1);
  97.   for(t=0; t<sufc; t++)
  98.     if (match(name,*(sufv+t)))  return(1);
  99.   return(0);
  100. }
  101.   
  102. void
  103. chfree(namesc, namesv)
  104.   int *namesc;
  105.   char ***namesv;
  106.   while ((*namesc)-->0)
  107.     if (*((*namesv)+(*namesc))!=NULL) free(*((*namesv)+(*namesc)));
  108.   if (*namesv!=NULL) free(*namesv);
  109. }
  110.  
  111. XRectangle assign(x,y,width,height)
  112.   int x,y,width,height;
  113. { XRectangle box;
  114.   box.x=x;
  115.   box.y=y;
  116.   box.width=width;
  117.   box.height=height;
  118.   return(box);
  119. }
  120.  
  121. void init2()
  122. { lstbox=assign(19,19,15*letwidth+4,rows*letheight+4);
  123.   upbox=assign(lstbox.x+lstbox.width,lstbox.y,15,15);
  124.   downbox=assign(upbox.x,lstbox.y+lstbox.height-15,15,15);
  125.   mvbox=assign(upbox.x,upbox.y+upbox.height,15,downbox.y-upbox.y-upbox.height);
  126.   fnamebox=assign(0,lstbox.y+lstbox.height+30,letwidth*45+4,letheight*3+4);
  127.   okbox=assign(upbox.x+upbox.width+50,50,letwidth*6+4,letheight+8);
  128.   cancelbox=assign(okbox.x,okbox.y+okbox.height+30,okbox.width,okbox.height);
  129.   messbox=assign(0,fnamebox.y+fnamebox.height+2,fnamebox.width,letheight+4);
  130. }
  131.  
  132. void init()
  133. { int ascent,descent,dummy;  
  134.   XCharStruct overall;
  135.   if (font_struct!=NULL) 
  136.   { XTextExtents(font_struct," ",1,&dummy,&ascent,&descent,&overall);
  137.     letwidth=overall.width;
  138.     letheight=ascent+descent;
  139.   }
  140.   init2();
  141.   myhint.width=fnamebox.x+fnamebox.width+4; myhint.height=messbox.y+messbox.height+4;
  142. }
  143.  
  144. inbox(box,myevent)
  145.   XRectangle box;
  146.   XEvent myevent;
  147. { if ( myevent.xbutton.x>=box.x && myevent.xbutton.x<=(box.x+box.width) &&
  148.     myevent.xbutton.y>=box.y && myevent.xbutton.y<=(box.y+box.height)) return(1);
  149.   else return(0);
  150. }
  151.  
  152. void Cleanlst(lst,dirl)
  153.   struct elm *lst;
  154.   int dirl;
  155. { int i;
  156.   for(i=1; i<=dirl; i++) lst[i].chose=0;
  157. }
  158.  
  159. void flash(mydisplay,mywindow,mygc,box)
  160.   Display *mydisplay; 
  161.   Window mywindow;
  162.   GC mygc;
  163.   XRectangle box;
  164. { int delay=200;
  165.   XEvent event;
  166.   XSetFunction(mydisplay,mygc,GXxor);
  167.   XFillRectangles(mystuff,&box,1);
  168.   XPeekEvent(mydisplay,&event); 
  169.   XFillRectangles(mystuff,&box,1); 
  170.   XSetFunction(mydisplay,mygc,GXcopy);
  171. }
  172.  
  173. void Xinit(write_read) 
  174.   int write_read;
  175. {
  176.  
  177. /*************
  178.   mydisplay=XOpenDisplay("");
  179. *************/
  180. /* TOBY Addition */
  181.   mydisplay = dpy;
  182.   myscreen = DefaultScreen(mydisplay);
  183.   mybackground= WhitePixel(mydisplay,myscreen);
  184.   myforeground= BlackPixel(mydisplay,myscreen);
  185.   font_struct=XLoadQueryFont(mydisplay,font);
  186.   init(); 
  187.   mywindow=XCreateSimpleWindow (mydisplay, DefaultRootWindow (mydisplay), myhint.x,
  188.     myhint.y, myhint.width, myhint.height,5,myforeground,mybackground);
  189.   XSetStandardProperties(mydisplay,mywindow,(write_read) ? "Save" :
  190.     "Load" ,"choosefile",None,NULL,0, &myhint);
  191.   mygc=XCreateGC(mydisplay,mywindow,0,0);
  192.   rmygc=XCreateGC(mydisplay,mywindow,0,0);
  193. }
  194.  
  195.  
  196. simple_choose(namesc,namesv,write_read)
  197.   int *namesc;
  198.   char ***namesv;
  199.   int write_read;
  200. {
  201.   if (firstcall==0)  { 
  202.     choose_dir=(char *)malloc(10);
  203.     strcpy(choose_dir,".");
  204.   }
  205.   choosefile(namesc,namesv,&choose_dir,choose_dir,write_read);
  206. }
  207.  
  208. choosefile(namesc,namesv,dpath,dr,write_read)
  209.   int *namesc;
  210.   char ***namesv;
  211.   char **dpath;
  212.   char *dr;
  213.   int write_read;
  214. { FILE  *fp;
  215.   DIR *dirp,*dumdir; 
  216.   char dum[300] ,inp[MaxName+20],  dum2[300],shell[300], dum3[MaxName+20],
  217.     text[10],inp_string[30],chrctr[2]; 
  218.   int i,found,chrows,k=0,flag=1,ch,dirl,kold,smooth=0,rdraw=0,chgdir=0,moved=0,
  219.     done=0,getting=0,x,y,pstn,start=1,n;
  220.   struct dirent *dp;
  221.   struct elm *lst;
  222.   strcpy(inp_string,"");
  223.   strcpy(dum2,dr);
  224.   lst=(struct elm *)(malloc(MaxFiles*sizeof(struct elm)));
  225.  
  226.   if (firstcall==0) 
  227.     Xinit(write_read);
  228.   else
  229.     XMapWindow(mydisplay,mywindow);
  230.   myhint.flags =PPosition | PSize; 
  231.   if (font_struct!=NULL)  
  232.   { XSetFont(mydisplay,mygc,font_struct->fid);
  233.     XSetFont(mydisplay,rmygc,font_struct->fid);
  234.   }
  235.   curs1=XCreateFontCursor(mydisplay,XC_top_left_arrow);
  236.   curs2=XCreateFontCursor(mydisplay,XC_watch);
  237.   XDefineCursor(mydisplay,mywindow,curs1);
  238.   XSetBackground(mydisplay,mygc,mybackground);
  239.   XSetForeground(mydisplay,mygc,myforeground);
  240.   XSetBackground(mydisplay,rmygc,myforeground);
  241.   XSetForeground(mydisplay,rmygc,mybackground);
  242.   XSelectInput(mydisplay,mywindow,ButtonPressMask | PointerMotionMask | 
  243.     ButtonReleaseMask | KeyPressMask | ExposureMask );
  244.   XMapRaised(mydisplay,mywindow);
  245.   while (done ==0)  
  246.   { if (flag) 
  247.     { XDefineCursor(mydisplay,mywindow,curs2); 
  248.       message("");
  249.       dirl=0;
  250.       sprintf(shell,"cd %s; pwd",dum2);
  251.       fp=popen(shell,"r");
  252.       fgets(dum2,100,fp);     
  253.       pclose(fp); 
  254.       n=strlen(dum2);
  255.       if (n>0 && dum2[n-1]=='\n') dum2[n-1]='\0';
  256.       dirp=opendir(dum2);
  257.       if (dirp!=NULL) 
  258.       { for (dp=readdir(dirp); dp!=NULL; dp=readdir(dirp))
  259.         { if (dirl<(MaxFiles-1))
  260.           { strncpy((lst[++dirl].name),(dp->d_name),MaxName-1);
  261.             if (strlen(dp->d_name)>=MaxName)
  262.             { message("Some File Names are too long ");}
  263.             strcpy(dum,dum2);
  264.             strcat(dum,"/");
  265.             lst[dirl].chose=0;
  266.             lst[dirl].ftype=!((dumdir=opendir(strcat(dum,lst[dirl].name)))==NULL);
  267.             if (lst[dirl].ftype) closedir(dumdir);
  268.             if (!((lst[dirl].ftype && shwdir) ||
  269.               (suflist(dp->d_name) && !(lst[dirl].ftype) ))) dirl--;
  270.           }
  271.           else {message("Too many files in the Directory"); }
  272.         } 
  273.         closedir(dirp);
  274.       }
  275.       flag=0;
  276.       XDefineCursor(mydisplay,mywindow,curs1); 
  277.     }
  278.     if ((start) && (*namesc>0))
  279.     { for(start=0;*namesc>0; (*namesc)--)
  280.       { found=0;
  281.         for(i=dirl; i>=1; i--)
  282.           if (match(lst[i].name,*((*namesv)+(*namesc)-1)) && (!lst[i].ftype)) 
  283.           { lst[i].chose=1; found=1; k=i-2;  k=max(min(dirl+2-rows,k),0);
  284.             if (write_read) {i=0;*namesc=0;} 
  285.           }
  286.         if (found) strcpy(inp_string,*((*namesv)));
  287.       }
  288.     }
  289.     if (rdraw) 
  290.     { rdraw=0;
  291.       XDrawImageString (mystuff,okbox.x+(okbox.width)/2-letwidth*2,
  292.         okbox.y+okbox.height/2+letheight/2,(chgdir) ? "OPEN" : " OK ",4);
  293.       for(i=1; i<=rows && (i+k)<=dirl; i++)
  294.         if (lst[i+k].chose) 
  295.         { XFillRectangle(mystuff,lstbox.x+1,lstbox.y+3+(i-1)*letheight,
  296.             15*letwidth,letheight);
  297.           XDrawString(rmystuff,lstbox.x+1,lstbox.y+i*letheight,
  298.             lst[i+k].name, min(strlen(lst[i+k].name),10));
  299.           if (lst[i+k].ftype) 
  300.             XDrawString(rmystuff,lstbox.x+1+letwidth*10,lstbox.y+i*letheight,"<dir>",5);
  301.         }
  302.         else
  303.         { XDrawImageString (mystuff, lstbox.x+1,lstbox.y
  304.             +i*letheight,strcat(strcpy(dum3,lst[i+k].name),"               "),10);
  305.           XDrawImageString(mystuff,lstbox.x+1+letwidth*10,lstbox.y+
  306.              i*letheight,(lst[i+k].ftype) ? "<dir>" : "     ",5);
  307.         }
  308.       for(; i<=rows; i++)
  309.       XDrawImageString (mydisplay, mywindow, mygc,lstbox.x+1,lstbox.y+i*letheight, 
  310.         "                       ", 15 );
  311.       XFillRectangles(mydisplay,mywindow,rmygc,&mvbox,1);
  312.       XDrawRectangles(mydisplay,mywindow,mygc,&mvbox,1);
  313.       XFillRectangle(mydisplay,mywindow,mygc,mvbox.x,mvbox.y+mvbox.height*
  314.         k/max((dirl+2),rows),mvbox.width,1+mvbox.height*rows/max(dirl+2,rows));
  315.     }
  316.     XNextEvent(mydisplay, &myevent);
  317.     switch(myevent.type) {
  318.     case ButtonRelease:
  319.       if (smooth) smooth=0;
  320.       break;
  321.     case MotionNotify:
  322.       if (smooth)  
  323.       { kold=k;
  324.         k=max((myevent.xmotion.y-mvbox.y)*max(dirl+2,rows),0)/mvbox.height;
  325.         k=max(min(dirl+2-rows,k),0); if (kold!=k) rdraw=1;
  326.       }
  327.       break;    
  328.     case MappingNotify:
  329.       XRefreshKeyboardMapping ( &myevent);
  330.       break;
  331.     case Expose:
  332.       if  (myevent.xexpose.count==0)
  333.         XGetWindowAttributes(mydisplay,mywindow, &sizeatt);
  334.       if (sizeatt.height!=myhint.height) 
  335.       { chrows=(sizeatt.height-myhint.height)/(letheight);
  336.         chrows=max(5-rows,chrows);
  337.         rows+=chrows; myhint.height+=chrows*letheight; init2();
  338.         k=max(min(dirl+2-rows,k),0);
  339.       }
  340.       XDrawRectangles(mystuff,&fnamebox,1); 
  341.       XDrawRectangles (mystuff,&lstbox,1);
  342.       XDrawRectangles (mystuff, &mvbox,1);
  343.       XDrawRectangles (mystuff, &upbox,1);
  344.       XDrawRectangles (mystuff, &downbox,1); 
  345.       XDrawRectangles (mystuff, &okbox,1); 
  346.       XDrawRectangles (mystuff, &cancelbox,1);  
  347.       XDrawImageString (mystuff,cancelbox.x+(cancelbox.width)/2
  348.         -letwidth*3,cancelbox.y+cancelbox.height/2+letheight/2,"CANCEL",6);
  349.       XDrawString(mystuff,10+fnamebox.x,(fnamebox.height+letheight)/2
  350.        +fnamebox.y-3,strcat(strcat(strcpy(dum3,prompt_string),inp_string),(getting)
  351.        ? "_" : " "),strlen(prompt_string)+strlen(inp_string)+1);
  352.       rdraw=1; 
  353.       break;
  354.     case KeyPress:
  355.       if (XLookupString(&myevent, text, 10, &mykey, 0)==1)
  356.       { if (!getting) 
  357.         { pstn = 0;
  358.           y =(fnamebox.height+letheight)/2+fnamebox.y-3;
  359.           x = 10+fnamebox.x + letwidth*strlen(prompt_string);
  360.           XDrawImageString(mystuff,x,y,"_                             ",30);
  361.           getting=1;
  362.         }
  363.         if((text[0] >= 32) && (text[0]!='/') && (text[0]!='{') && (text[0]!='}') 
  364.           && (text[0] <= 126) && pstn<30) 
  365.         { XDrawImageString(mystuff,x,y,text,1);
  366.           x += letwidth;
  367.           XDrawImageString(mystuff,x,y,"_",1);
  368.           inp_string[pstn] = text[0];
  369.           pstn++;
  370.         }
  371.         if(((text[0] == 8) || (text[0] == 127)) && (pstn>0)) 
  372.         { pstn--;
  373.           x -= letwidth;
  374.           XDrawImageString(mystuff,x,y,"_ ",2);
  375.         }
  376.         if (text[0]=='\r') 
  377.         { getting=0;
  378.           XDrawImageString(mystuff,x,y,"  ",2);  
  379.           inp_string[pstn] = 0;
  380.           if (pstn>0)
  381.           { Cleanlst(lst,dirl);
  382.             chgdir=0;
  383.             rdraw=1;
  384.             found=0;
  385.             message("");
  386.             for(i=dirl; i>=1; i--)
  387.               if (match(lst[i].name,inp_string) && (!lst[i].ftype)) 
  388.               { lst[i].chose=1; found=1; k=i-2;  k=max(min(dirl+2-rows,k),0);
  389.                 if (write_read) i=0; 
  390.               }
  391.             if ((!found) && (!write_read)) {message("Not found");}
  392.             if ((found) && (write_read)) {message("Note: Already Exists");}
  393.           }
  394.         }
  395.         inp_string[pstn] = 0;
  396.       }
  397.       break; 
  398.     case ButtonPress:
  399.       if (inbox(cancelbox,myevent)) done=2;
  400.       if (inbox(okbox,myevent)) 
  401.       if (chgdir) 
  402.       { XDefineCursor(mydisplay,mywindow,curs2); 
  403.  
  404.         flash(mystuff,okbox); 
  405.         strcat(dum2,"/");
  406.         strcat(dum2,inp);
  407.         flag=1; k=0; 
  408.         rdraw=1;
  409.         chgdir=0;
  410.       }
  411.       else done=1;
  412.       if (inbox(downbox,myevent)) { flash(mystuff,downbox); k++; }
  413.       if (inbox(upbox,myevent)) {flash(mystuff,upbox); k--; }
  414.       if (inbox(mvbox,myevent))
  415.       { k=(myevent.xbutton.y-mvbox.y)*max(dirl+2,rows)/mvbox.height; smooth=1;}
  416.       k=max(min(dirl+2-rows,k),0);
  417.       if (inbox(upbox,myevent) || inbox(downbox,myevent) || inbox(mvbox,myevent)) 
  418.         rdraw=1;
  419.       if (inbox(lstbox,myevent))
  420.       { ch=(myevent.xbutton.y-(lstbox.y+3))/letheight+1; 
  421.         if (ch+k>dirl) ch=0;
  422.         rdraw=1;
  423.         if (chgdir) { Cleanlst(lst,dirl); chgdir=0;}
  424.         lst[ch+k].chose=(!lst[ch+k].chose);
  425.         if ((ch>=1) && (ch<=rows) && ((lst[ch+k].ftype==1) || (write_read)))   
  426.         { strcpy(inp,lst[ch+k].name);
  427.           Cleanlst(lst,dirl);
  428.           lst[ch+k].chose=1;
  429.           if (lst[ch+k].ftype) chgdir=1;
  430.         }
  431.       }
  432.       break;
  433.     }
  434.   }
  435. /**** TOBY change: dumps core! 
  436.   if (firstcall==1) chfree(namesc,namesv);
  437. ****/
  438.  
  439.   *namesc=0;
  440.   if (done==2) {*namesv=NULL; *dpath=NULL; }
  441.   else
  442.   { *namesv=(char **)malloc(dirl*sizeof(char *));
  443.     for(i=1; i<=dirl; i++)
  444.       if (lst[i].chose)
  445.       { 
  446.         *((*namesv)+(*namesc))=(char *)malloc(strlen(lst[i].name)+2);
  447.         strcpy(*((*namesv)+(*namesc)),lst[i].name);
  448.         (*namesc)++;
  449.       }
  450.   /*  if (dpath!=NULL) free(dpath); */
  451.     if ((*namesc)==0 && write_read==1 && strlen(inp_string)>0) 
  452.     {
  453.         *((*namesv)+(*namesc))=(char *)malloc(strlen(inp_string)+2);
  454.         strcpy(*((*namesv)+(*namesc)),inp_string);
  455.         (*namesc)++;
  456.     }
  457.       
  458.     *dpath=(char *)malloc(strlen(dum2)+2);
  459.     strcpy(*dpath,dum2);
  460.   }
  461.   if (firstcall==0) firstcall=1;
  462.   XUnmapWindow(mydisplay,mywindow);
  463.   return(*namesc);
  464. }
  465.  
  466. void
  467. choose_exit()
  468. {
  469.  
  470.   XFreeGC (mydisplay,mygc); 
  471.   XDestroyWindow (mydisplay,mywindow);
  472. /* TOBY change
  473.   XCloseDisplay (mydisplay);
  474. */
  475.   firstcall=0;
  476. }
  477.  
  478.  
  479.  
  480.  
  481.